Loading...
 

External (2.example)

Define customer derivations

The following imaginary project structure is given, in which the programme is started with the following parameters:

cx_osuo.exe project.cxp --extern_file project.ext

project.ext
Msg(PROCESS_DATA) Extern(basicFunctions, File(basicFunctions.mod)) Extern(advancedFunctions, File(advancedFunctions.mod)) : basicFunctions Extern(businessLogic, File(businessLogic.mod), triggeredBy(PROCESS_DATA)) : advancedFunctions

project.cxp
Module(project) [ INITIALIZE: // ... data SendMsg(PROCESS_DATA) // ... ]

Now the behaviour of the module businessLogic is to be adapted for a customer (e.g. "ACME"), i.e. a customer-specific derivative is to be written. Since only a small part of the functionality is to be adapted, it makes little sense to rewrite the entire module. Instead, the majority of the existing logic should be taken over from the businessLogic module by inheritance and only a specific part should be adapted. Writing the module from scratch would also have the disadvantage that adaptations to the businessLogic module in the main project would not affect the customer project.

The customisation can be easily defined without having to modify the code of the main project. All that is required is to create an .ext file for the customer with the following content:

acme.ext
#include "CX_SYSTEM\\project.ext" Extern(businessLogic_acme, File(businessLogic_acme.mod), triggeredBy(PROCESS_DATA), overwrites(businessLogic)) : businessLogic

And here is a sketched module implementation for the customer module. It is not necessary to specify the base module by module(...), because there is an external() specification for the module and the base module is defined there.

businessLogic_acme.mod
Module(businessLogic_acme) [ Define(CoreLogic) // Some modified logic ; ]

With this adjustment, the project must now also be started with the new .ext file as follows

cx_osuo.exe project.cxp --extern_file acme.ext

The project will now use the adapted customer logic at all points, because the original module has been deactivated by overwrites(businessLogic). By means of overwrites(...) a standard solution can be adapted to customer requirements without having to integrate these adaptations directly into the standard.

What does deactivated mean?

The module is not really deactivated. overwrites(...) only causes the module to be no longer loaded when sending the triggeredBy(...) messages that were previously logged on. The provider is also logged off if it has registered as such via provides(...). Since it no longer reacts to messages, it appears "deactivated". However, another module can still derive from a "deactivated" module and thus use its functionality.

The module is thus deactivated in the sense that it no longer becomes active itself as soon as a trigger message that was previously logged on is sent, but it can still be used unchanged in derivatives.

What would happen without overwrites?

Since overwrites(...) disables the trigger messages of the original module, without overwriting there would be two modules responding to the same messages and in SendMsg(PROCESS_DATA) the system would try to load two modules, one derived from the other, which is forbidden because a module cannot be instantiated if there is a module derived from it at the same time. In this case the system would only load the derived module and would therefore behave in the same way as it would if overwrites(...) were specified.

Attention: You should not rely on this behaviour, as such a constellation still represents an error and could be reported as an error at startup in future ClassiX versions.

However, if the triggeredBy(...) were also missing in the derived customer module, the system would return an error because the message would only instantiate the base module, which is not allowed.